﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using System.IO;
using Newtonsoft.Json.Converters;
using System.Globalization;
using Newtonsoft.Json.Serialization;
using System.Linq.Expressions;

namespace OpenAPI.CommonLib
{
	public static class JsonConvertExd
	{
		public static string SerializeObjectWithIgnore(object value, List<string> ignoreList)
		{
			if (ignoreList == null)
			{
				ignoreList = new List<string>();
			}
			IsoDateTimeConverter dateC = new IsoDateTimeConverter() { DateTimeFormat = "yyyy-MM-dd HH:mm:ss.ffff" };
			var formatting = Formatting.None;
			var converters = new JsonConverter[] { dateC };
			JsonSerializerSettings settings = (converters != null && converters.Length > 0)
										 ? new JsonSerializerSettings { Converters = converters }
										 : null;

			JsonSerializer jsonSerializer = JsonSerializer.Create(settings);
			jsonSerializer.ContractResolver = new JsonIgnoreExDefaultContractResolver(true, ignoreList);
			StringBuilder sb = new StringBuilder(256);
			StringWriter sw = new StringWriter(sb, CultureInfo.InvariantCulture);
			using (JsonTextWriter jsonWriter = new JsonTextWriter(sw))
			{
				jsonWriter.Formatting = formatting;
				jsonSerializer.Serialize(jsonWriter, value);
			}
			string s = sw.ToString();
			return s;
		}

		public static T Deserialize<T>(string value)
		{
			return JsonConvert.DeserializeObject<T>(value);
		}
		public class Test
		{
			public int age { get; set; }
			public string name { get; set; }
			public int sex { get; set; }
		}

		public static string GetPropertyName<T>(Expression<Func<T, object>> expr)
		{
			string rtn = "";
			if (expr.Body is UnaryExpression)
			{
				rtn = ((MemberExpression)((UnaryExpression)expr.Body).Operand).Member.Name;
			}
			else if (expr.Body is MemberExpression)
			{
				rtn = ((MemberExpression)expr.Body).Member.Name;
			}
			else if (expr.Body is ParameterExpression)
			{
				rtn = ((ParameterExpression)expr.Body).Type.Name;
			}
			return rtn;
		}
		static void test()
		{
			List<Test> test = new List<Test>();
			Test ss = new Test
			{
				age = 19,
				sex = 1,
				name = "cgyqu"
			};
			test.Add(ss);
			var s = from p in test
					where p.name == "cgyqu"
					select p;
			//Console.WriteLine(GetPropertyName<Test>(x=>x.name));
			Console.WriteLine(SerializeObjectWithIgnore(s, null));
		}
	}

	public class JsonIgnoreExDefaultContractResolver : DefaultContractResolver
	{
		private List<string> ignoreList;
		public JsonIgnoreExDefaultContractResolver(bool shareCache, List<string> ignoreList)
		{
			this.ignoreList = ignoreList;
		}
		protected override JsonProperty CreatePropertyFromConstructorParameter(JsonProperty matchingMemberProperty, System.Reflection.ParameterInfo parameterInfo)
		{
			return base.CreatePropertyFromConstructorParameter(matchingMemberProperty, parameterInfo);
		}

		protected override JsonProperty CreateProperty(System.Reflection.MemberInfo member, Newtonsoft.Json.MemberSerialization memberSerialization)
		{
			var jsp = base.CreateProperty(member, memberSerialization);
			{
				if (ignoreList != null && ignoreList.Count > 0)
				{
					string fieldName = member.DeclaringType + "." + member.Name;
					jsp.Ignored = ignoreList.Contains(fieldName);
				}
			}
			return jsp;
		}
	}
}
